package cn.bearspark.currency.provider.service.impl;

import cn.bearspark.common.util.ConvertInfoUtil;
import cn.bearspark.currency.dto.CurrencyBaseInfoDTO;
import cn.bearspark.currency.provider.dao.mapper.CoinMapper;
import cn.bearspark.currency.provider.dao.mapper.CurrencyMapper;
import cn.bearspark.currency.provider.dao.mapper.MeritMapper;
import cn.bearspark.currency.provider.key.CurrencyCacheKeyBuilder;
import cn.bearspark.currency.provider.service.CurrencyService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author f
 */
@Service
public class CurrencyServiceImpl implements CurrencyService {

    /**
     * 设置货币基础信息的缓存的有效期（单位：ms），默认是 10min
     */
    private static final int CURRENCY_BASE_INFO_CACHE_EXPIRE = 1000 * 60 * 10;

    private final CurrencyMapper currencyMapper;
    private final MeritMapper meritMapper;
    private final CoinMapper coinMapper;

    private final RedisTemplate<String, Object> redisTemplate;
    private final CurrencyCacheKeyBuilder currencyCacheKeyBuilder;

    public CurrencyServiceImpl(CurrencyMapper currencyMapper, MeritMapper meritMapper, CoinMapper coinMapper,
                               RedisTemplate<String, Object> redisTemplate,
                               CurrencyCacheKeyBuilder currencyCacheKeyBuilder) {
        this.currencyMapper = currencyMapper;
        this.meritMapper = meritMapper;
        this.coinMapper = coinMapper;
        this.redisTemplate = redisTemplate;
        this.currencyCacheKeyBuilder = currencyCacheKeyBuilder;
    }

    @Override
    public CurrencyBaseInfoDTO getBaseInfo(long userId) {
        String cacheKey = currencyCacheKeyBuilder.buildCurrencyBaseInfoKey(userId);
        CurrencyBaseInfoDTO currencyBaseInfoDTO = (CurrencyBaseInfoDTO) redisTemplate.opsForValue().get(cacheKey);
        if (currencyBaseInfoDTO != null) {
            return currencyBaseInfoDTO;
        }

        currencyBaseInfoDTO = ConvertInfoUtil.convert(
                currencyMapper.getCurrencyBaseInfo(userId), CurrencyBaseInfoDTO.class);
        redisTemplate.opsForValue().set(cacheKey, currencyBaseInfoDTO,
                CURRENCY_BASE_INFO_CACHE_EXPIRE, TimeUnit.MILLISECONDS);

        return currencyBaseInfoDTO;
    }

    @Override
    public void initCurrency(long userId) {
        meritMapper.insert(userId);
        coinMapper.insert(userId);
    }

    @Override
    public boolean deductMerit(long userId) {
        if (meritMapper.decrBalance(userId) == 0) {
            return false;
        }
        redisTemplate.delete(currencyCacheKeyBuilder.buildCurrencyBaseInfoKey(userId));
        return true;
    }
}
